/**
 * 2017年5月23日
 */
package org.bjtu.word2vec.gui;

import java.awt.GridBagConstraints;
import java.awt.event.MouseEvent;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import org.bjtu.word2vec.listener.AbstractMouseListener;

import cn.edu.bjtu.interfaces.wordfilters.IWord;
import cn.edu.bjtu.model.dl4jword2vec.DL4jWordVecModel;
import cn.edu.bjtu.model.word2vec.util.WordInWord2Vec;

/**
 * @author Alex
 *
 */
public class NearestWordsFrame extends PoolSupport {

	private static final long serialVersionUID = -5042065101863787407L;
	JFrame parent = null;
	JTextField wordArea;
	JTextField k_nearestArea;
	JButton select;
	JTextArea showNearestWords;
	private DL4jWordVecModel model = DL4jWordVecModel.getInstance();
	private ThreadFactory _tf = new ThreadFactory() {
		AtomicInteger at = new AtomicInteger(0);

		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(r);
			t.setName("NearestWordsFrame-Event-Handler-Pool-"
					+ at.getAndIncrement());
			return t;
		}
	};
	private ExecutorService eventHandler = Executors
			.newFixedThreadPool(3, _tf);

	public NearestWordsFrame(JFrame parent) {
		this.parent = parent;
		init();
		setLayout(gbl);
		setSize(1024, 768);
		setVisible(true);
		setTitle("求近似词");
		initEvent();
	}

	private void initEvent() {
		select.addActionListener((e) -> {
			logger.info("Event");
			eventHandler.execute(() -> {
				String word = wordArea.getText().toString().trim();
				String top_k = k_nearestArea.getText().toString()
						.trim();
				if (word.length() == 0 || top_k.length() == 0) {
					showMessage("请输入词或k值");
				} else {
					 select.setEnabled(true);
					IWord i = new WordInWord2Vec(word);
					Iterator<IWord> words = model.getTopKSimilar(
							Integer.parseInt(top_k), i);
					if (words != null) {
						StringBuilder sb = new StringBuilder();
						sb.append("查询的是与  \""+word+"\"  最近的  \""+top_k+"\" 个词"+"\r\n");
						while (words.hasNext()) {
							sb.append(
									words.next().getWord() + "\r\n");
						}
						showNearestWords.setText(sb.toString());
					} else {
						showMessage("模型中没有该词");

					}
				}

			});
		});
		wordArea.addMouseListener(new AbstractMouseListener(){
			@Override
			public void mousePressed(MouseEvent e) {
				wordArea.setText("");
			}
		});
		k_nearestArea.addMouseListener(new AbstractMouseListener(){
			@Override
			public void mousePressed(MouseEvent e) {
				k_nearestArea.setText("");
			}
			@Override
			public void mouseExited(MouseEvent e) {
		     	if(!isNumeric(k_nearestArea.getText().toString())){
		     		showMessage("输入的数据格式不对,请重新输入");
		     	    select.setEnabled(false);
		     	}else{
		     		select.setEnabled(true);
		     	}
			}
		});
		
	}

	private void init() {
		select = new JButton("查询");
		wordArea = new JTextField("请输入需要查询的词");
		wordArea.setSize(100,20);
		k_nearestArea = new JTextField("请输入k值");
		k_nearestArea.setSize(100,20);
		showNearestWords = new JTextArea();
		addComp(wordArea);
		addComp(k_nearestArea);
		addComp(select);
		addComp(showNearestWords);
		gbl.setConstraints(wordArea, new GBC(0, 13).setGridWidth(3));
		gbl.setConstraints(k_nearestArea, new GBC(3, 13).setGridWidth(2));
		gbl.setConstraints(select, new GBC(5, 13).setGridWidth(2));
		gbl.setConstraints(showNearestWords,
				new GBC(7, 13).setGridWidth(8).setWx(8).setWy(1)
						.setFill(GridBagConstraints.BOTH));

	}

	private void showMessage(String msg) {
		showNearestWords.setText(msg);
	}
	public boolean isNumeric(String str){ 
		   Pattern pattern = Pattern.compile("[0-9]*"); 
		   Matcher isNum = pattern.matcher(str);
		   if( !isNum.matches() ){
		       return false; 
		   } 
		   return true; 
		}
}
